// 通用工具（从 MerchantApp 迁移，无业务数据）
export const formatDate = (date, format = 'YYYY-MM-DD HH:mm:ss') => {
  if (!date) return ''
  const d = new Date(date); if (isNaN(d.getTime())) return ''
  const Y=d.getFullYear(), M=String(d.getMonth()+1).padStart(2,'0'), D=String(d.getDate()).padStart(2,'0')
  const H=String(d.getHours()).padStart(2,'0'), m=String(d.getMinutes()).padStart(2,'0'), s=String(d.getSeconds()).padStart(2,'0')
  return format.replace('YYYY',Y).replace('MM',M).replace('DD',D).replace('HH',H).replace('mm',m).replace('ss',s)
}
export const debounce=(fn,delay=300)=>{ let t=null; return function(...args){ if(t) clearTimeout(t); t=setTimeout(()=>fn.apply(this,args),delay) } }
export const throttle=(fn,delay=300)=>{ let t=null; return function(...args){ if(!t){ t=setTimeout(()=>{ fn.apply(this,args); t=null },delay) } } }
export const deepClone=(obj)=>{ if(obj===null||typeof obj!=='object') return obj; if(Array.isArray(obj)) return obj.map(deepClone); const c={}; Object.keys(obj).forEach(k=>c[k]=deepClone(obj[k])); return c }
export const getImageUrl=(path)=>{ if(!path) return ''; if(path.startsWith('http')||path.startsWith('/')) return path; return `/static/images/${path}` }

